package model.jgap;
//
//import java.util.ArrayList;
//import java.util.Date;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
//import model.market.DailyParameterSet;
//import model.market.MarketException;
//import model.market.DayMarketInfo;
//import model.market.MarketManager;
//import model.market.Position;
//import model.stats.CorrelationCalculation;
//import model.trader.MomentumTrader;
//import model.trader.Opportunist;
//import model.trader.Trader;
//import model.trader.ValueInvestor;
//
//import org.jgap.FitnessFunction;
//import org.jgap.Gene;
//import org.jgap.IChromosome;
//import org.jgap.impl.CompositeGene;
//import org.jgap.impl.DoubleGene;
//import org.jgap.impl.IntegerGene;
//
///**
// * AMJGAP LOW: comments.
// * 
// * @author Administrator
// * 
// */
public class MarketModelFitnessFunction {//extends FitnessFunction {
//	private static final int SETTLE_DOWN_ITERATIONS = 20;
//	private double[] marketPrices;
//
//	public MarketModelFitnessFunction(double[] marketPrices) {
//		this.marketPrices = marketPrices;
//	}
//
//	/**
//	 * 
//	 */
//	public double evaluate(IChromosome a_subject) {
//		Gene[] genes = a_subject.getGenes();
//		// 0 is value investor..
//		
//		MarketManager manager = new MarketManager();
//		
//		configureMarket(genes, manager);
//		int settleDownIterations = SETTLE_DOWN_ITERATIONS;
//		try {
//			manager.execute(marketPrices.length+settleDownIterations);//AMJGAP: temp possibly SETTLE_DOWN_ITERATIONS);
//		} catch (MarketException e) {
//			int managedIterations = manager.getPrices().length;
//			//System.out.println("Error at: "+managedIterations);
//			return managedIterations;
//		}
//		
//		double[] modelPrices = new double[marketPrices.length];
//		for(int i=settleDownIterations;i<manager.getPrices().length;i++){
//			DayMarketInfo info = manager.getPrices()[i];
//			modelPrices[i-settleDownIterations] = info.getMarketPrice();
//		}
//		
//		//AMJGAP LOW: remove risk free?
//		//AM: convert asset prices to asset returns
//		double[] marketReturns = new double[marketPrices.length-1];
//		double[] modelReturns = new double[modelPrices.length-1];
//		for(int i=1;i<modelReturns.length;i++){
//			marketReturns[i]= (marketPrices[i]-marketPrices[i-1])/marketPrices[i-1];
//			modelReturns[i]=(modelPrices[i]-modelPrices[i-1])/modelPrices[i-1];
//		}
//		
//		double correlation = new CorrelationCalculation().getCorrelationCoefficient(marketReturns, modelReturns);
////		if(correlation>correlationmax){
////			correlationmax=correlation;
////			System.out.println("\nnew correlation max: "+correlationmax);
////			System.out.println("Model PRices: {");
////			for(int i=0;i<modelPrices.length;i++){
////				System.out.println(""+modelPrices[i]);
////			}
////			System.out.println("Model PRices: }");
////			
////		}
//		//AM: temp bullshit..return manager.getPrices().length + manager.getPrices().length*10 * correlation*correlation;
//	
//		//AM: temp bullshit..
//		double scoreSum=0;
//		for(int i=0;i<modelReturns.length;i++){
//			double difference = Math.max(modelReturns[i]/(marketReturns[i]-.08),//AMJGAP: -.1 is just to account for growth in real asset. temptemp.
//										(marketReturns[i]-.08)/modelReturns[i])-1;
//			if(difference<0){
//				//AM: a bad score...one negative, one positive..
//				difference=3;//1/difference;
//			}
//			if(difference<.2){
//				scoreSum += 100;
//			}else{
//				scoreSum+=20/difference;
//			}
//		}
//		
////		double scoreSum=0;
////		for(int i=0;i<modelPrices.length;i++){
////			double difference = (modelPrices[i]/modelPrices[0])/(marketPrices[i]/marketPrices[0]);
////			if(difference<1){
////				difference=1/difference;
////			}
////			scoreSum+=difference-1;
////		}
////		
////		double sumComponent = Math.log(1/scoreSum+1)*manager.getPrices().length*100;
//
//		
//		
//		double scoreRet=(manager.getPrices().length-settleDownIterations)+scoreSum; //+sumComponent;
//		if(correlation>0){
//			scoreRet+=2000*correlation;
//		}
//		if(scoreRet>correlationmax){
//			correlationmax=scoreRet;
//			System.out.print(" new top score: "+correlationmax+" jolt: "+manager.getJolt());
//			System.out.println(" correlation component: "+correlation+" scoresum "+scoreSum);
//	
//		}
//		return scoreRet;
//	}
//
//	private void configureMarket(Gene[] genes, MarketManager manager) {
//		
//		//manager.fairPrice=((IntegerGene)genes[4]).intValue();
//		
//		CompositeGene initTraders = (CompositeGene)genes[0];
//		//List<Gene> traderAndPositions = (List<Gene>)initTraders.ge();
//		for(int i=0;i<initTraders.size();i++){
//			TraderPositionComposite traderAndPos= (TraderPositionComposite)initTraders.geneAt(i);
//			manager.register(traderAndPos.getTrader(), traderAndPos.getPosition());
//		}
//
//		manager.setJolt(((DoubleGene)genes[2]).doubleValue());
//		
//		CompositeGene dailyTraders = (CompositeGene)genes[4];
////		CompositeGene interestRates = (CompositeGene)genes[2];
//		CompositeGene fairPriceMovements = (CompositeGene)genes[3];
//		
//		List<DailyParameterSet> dailyParametersList = new ArrayList<DailyParameterSet>();
//		for(int i=0;i<SETTLE_DOWN_ITERATIONS;i++){
//			DailyParameterSet params = new DailyParameterSet();
//			dailyParametersList.add(params);
//		}
//		
//		for(int i=0;i<marketPrices.length;i++){
//			DailyParameterSet params = new DailyParameterSet();
//			dailyParametersList.add(params);
//			
//			params.setFairValueMovement(((DoubleGene)fairPriceMovements.geneAt(i)).doubleValue());
//			//AMJGAP: temp params.setShareCashflowRate(((DoubleGene)interestRates.geneAt(i)).doubleValue());
//			
//			CompositeGene traderGene = (CompositeGene)dailyTraders.geneAt(i);
//			TraderPositionComposite firstTrader = (TraderPositionComposite)traderGene.geneAt(0);
//			TraderPositionComposite secondTrader = (TraderPositionComposite)traderGene.geneAt(1);
//			TraderPositionComposite thirdTrader = (TraderPositionComposite)traderGene.geneAt(2);
//			
//			Map<Trader, Position> traderMap = new HashMap<Trader, Position>();
//			traderMap.put(firstTrader.getTrader(), firstTrader.getPosition());
//			traderMap.put(secondTrader.getTrader(), secondTrader.getPosition());
//			traderMap.put(thirdTrader.getTrader(), thirdTrader.getPosition());
//			params.setTraders(traderMap);
//			
//			
//		}
//		manager.setDailyParameters(dailyParametersList);
//
//		
//		//AMJGAP: temp possibly, deparamaterised opportunists..
//		manager.register(new Opportunist(.01,2000),new Position(30000000));
//		manager.register(new Opportunist(.02,2000),new Position(30000000));
//		manager.register(new Opportunist(.03,2000),new Position(30000000));
//		manager.register(new Opportunist(.04,2000),new Position(30000000));
//		manager.register(new Opportunist(.05,2000),new Position(30000000));
//		manager.register(new Opportunist(.06,2000),new Position(30000000));
//		manager.register(new Opportunist(.07,2000),new Position(30000000));
//		manager.register(new Opportunist(.08,2000),new Position(30000000));
//		manager.register(new Opportunist(.09,2000),new Position(30000000));
//		manager.register(new Opportunist(.1,4000),new Position(30000000));
//		manager.register(new Opportunist(.12,4000),new Position(30000000));
//		manager.register(new Opportunist(.14,6000),new Position(30000000));
//		manager.register(new Opportunist(.16,6000),new Position(30000000));
//		manager.register(new Opportunist(.18,6000),new Position(30000000));
//		manager.register(new Opportunist(.2,20000),new Position(30000000));
//		manager.register(new Opportunist(.25,30000),new Position(30000000));
//		manager.register(new Opportunist(.3,100000),new Position(30000000));
//		manager.register(new Opportunist(.4,240000),new Position(30000000));
//		manager.register(new Opportunist(.5,400000),new Position(30000000));
//		manager.register(new Opportunist(.65,400000),new Position(30000000));
//		manager.register(new Opportunist(.85,800000),new Position(30000000));
//		//this guy is the buffer that stops our market blowin up..
//		manager.register(new Opportunist(1,2000000),new Position(30000000));
//		//manager.register(new Opportunist(1.5,1000000),new Position(30000000));
//		manager.register(new Opportunist(2,20000000),new Position(30000000));
//		manager.register(new Opportunist(4,20000000),new Position(30000000));
//		manager.register(new Opportunist(6,100000000),new Position(30000000));
//		
//		manager.register(new Opportunist(.01,2000),new Position(30000000));
//		manager.register(new Opportunist(.02,2000),new Position(30000000));
//		manager.register(new Opportunist(.03,2000),new Position(30000000));
//		manager.register(new Opportunist(.04,2000),new Position(30000000));
//		manager.register(new Opportunist(.05,2000),new Position(30000000));
//		manager.register(new Opportunist(.06,2000),new Position(30000000));
//		manager.register(new Opportunist(.07,2000),new Position(30000000));
//		manager.register(new Opportunist(.08,2000),new Position(30000000));
//		manager.register(new Opportunist(.09,2000),new Position(30000000));
//		manager.register(new Opportunist(.1,4000),new Position(30000000));
//		manager.register(new Opportunist(.12,4000),new Position(30000000));
//		manager.register(new Opportunist(.14,6000),new Position(30000000));
//		manager.register(new Opportunist(.16,6000),new Position(30000000));
//		manager.register(new Opportunist(.18,6000),new Position(30000000));
//		manager.register(new Opportunist(.2,20000),new Position(30000000));
//		manager.register(new Opportunist(.25,30000),new Position(30000000));
//		manager.register(new Opportunist(.3,100000),new Position(30000000));
//		manager.register(new Opportunist(.4,240000),new Position(30000000));
//		manager.register(new Opportunist(.5,400000),new Position(30000000));
//		manager.register(new Opportunist(.65,400000),new Position(30000000));
//		manager.register(new Opportunist(.85,800000),new Position(30000000));
//		//this guy is the buffer that stops our market blowin up..
//		manager.register(new Opportunist(1,2000000),new Position(30000000));
//		//manager.register(new Opportunist(1.5,1000000),new Position(30000000));
//		manager.register(new Opportunist(2,20000000),new Position(30000000));
//		manager.register(new Opportunist(4,20000000),new Position(30000000));
//		manager.register(new Opportunist(6,100000000),new Position(30000000));
//		
//		
//	}
//	
//	//AMJGAP: 5 should not be referred to directly
//	//AMJGAP: after completing full iterations, why is there an error thing coming up?
//	public double[] evaluateWithResults(IChromosome a_subject){
//		
//		Gene[] genes = a_subject.getGenes();
//		
//		MarketManager manager = new MarketManager();
//		
//		configureMarket(genes, manager);
//		int settleDownIterations = SETTLE_DOWN_ITERATIONS;
//		try {
//			//AM: 5 extra iterations to see what happens next!!
//			manager.execute(marketPrices.length+settleDownIterations+5);
//		} catch (MarketException e) {
//			int managedIterations = manager.getPrices().length;
//			System.out.println("Error at: "+managedIterations);
//			//throw new RuntimeException(e);
//		}
//		DayMarketInfo[] prices = manager.getPrices();
//		double[] results = new double[marketPrices.length+5];
//		int count=0;
//		System.out.println("\n\n------------------------");
//		for(int i=settleDownIterations;i<prices.length;i++){
//			results[count++]=prices[i]==null?0:prices[i].getMarketPrice();
//			Position momPos = prices[i].getClassPositions().get(MomentumTrader.class);
//			Position valPos = prices[i].getClassPositions().get(ValueInvestor.class);
//			double marketPrice =prices[i].getMarketPrice();
//			
//			System.out.println("Asset price:	"+(marketPrices.length>i-settleDownIterations?marketPrices[i-settleDownIterations]:"")+
//							"	Fairprice	"+prices[i].getFairPrice()+
//							"	marketprice	"+marketPrice+
//							"	value/momentum	"+(valPos.getWorth(marketPrice)/momPos.getWorth(marketPrice)));
//		}
//		System.out.println("\n\n------------------------");
//		return results;
//		
//	}
//	
//	
//	private double correlationmax=0;
//
//	public double getCorrelationmax() {
//		return correlationmax;
//	}
}
